<template>
  <div class="animate__animated animate__fadeIn">
    <div class="room" ref="room">
      <div class="room-left" v-show="user" >
        <img :src="getImageUrl(user.avatar)" />
        <p
          v-for="(item, index) in iconList"
          :key="item"
          :class="[item, { active: iconCurrentIndex === index }]"
          class="iconfont"
        ></p>
      </div>
      <div class="room-center">
        <div class="center-h">
          <p>当前用户列表</p>
        </div>
        <div class="center-b">
          <ul>
            <li class="user-item" v-for="item in userList" :key="item.username">
              <img :src="getImageUrl(item.avatar)"/>
              <span class="block whitespace-nowrap text-ellipsis overflow-hidden">{{ item.username }}</span>
            </li>
          </ul>
        </div>
      </div>
      <div class="room-right">
        <p class="name">聊天室({{ userListLength }})</p>
        <div class="chatcontent">
          <ul class="join" ref="joinUs">
            <li v-for="item in joinRoom" :key="item.username">
              欢迎{{ item.username }}加入群聊
            </li>
            <li
              v-for="(item1, index) in messageContent"
              :key="index"
              :class="{
                'my-message': item1.type === 1 ? true : false,
                'other-message': item1.type === 2 ? true : false,
              }"
            >
              <div v-if="item1.type === 3">{{ item1.username }}离开了群聊</div>
              <div v-if="item1.type === 1">
                <img
                  :src="item1.file"
                  class="file"
                  v-if="item1.file"
                  @load="loadOverImg"
                  preview="1"
                />
                <span v-else>{{ item1.msg }}</span>
                <img
                  :src="getImageUrl(item1.avatar)"
                  class="avatar"
                />
              </div>
              <div v-if="item1.type === 2">
                <img
                  :src="getImageUrl(item1.avatar)"
                  class="avatar"
                />
                <p class="username">{{ item1.username }}</p>
                <img
                  :src="item1.file"
                  class="file"
                  v-if="item1.file"
                  @load="loadOverImg"
                  preview="1"
                />
                <p class="content" v-else>{{ item1.msg }}</p>
              </div>
            </li>
          </ul>
        </div>
        <div class="sendMessage">
          <div class="icon">
            <span
              class="iconfont icon-smile"
              @click="emojiShow = !emojiShow"
            ></span>
            <div
              class="emoji"
              tabindex="1"
              v-show="emojiShow"
              @blur="handleEmojiBlur"
            >
              <span
                v-for="item in emojiList"
                :key="item.codes"
                @click="handleEmoji(item)"
                >{{ item.char }}</span
              >
            </div>
            <label class="iconfont icon-wenjianjia" for="file"></label>
            <input
              type="file"
              style="display: none"
              id="file"
              @change="handleFile"
            />
            <span class="iconfont icon-jietu" @click="handleCanvas"></span>
          </div>
          <textarea
            cols="80"
            rows="5"
            v-model="textarea"
            @keyup.enter="handlePress"
          ></textarea>
          <!-- <button class="sendMessage" >发送</button> -->
          <el-button class="btn-sendMessage" type="success" @click="sendContentToServe" plain round>
            <el-icon><Upload /></el-icon>发送
          </el-button>
        </div>
      </div>
    </div>
  </div>
  
</template>

<script setup lang="ts">
import { ref, reactive, toRefs, computed, watch, onMounted, onUpdated } from "vue";
import html2canvas from "html2canvas";
import emoji from "../assets/emoji.json";
import useStore from "../stores"

const { interactState } = useStore()

type User = { avatar: string, msg: string, username: string }
type UserList = Array<{ avatar: string, username: string }>
type Message = { avatar: string, msg: string, username: string, file?: "" }

type Props = {
  user: User;
  userList: UserList;
  message: Message;
}

//接收父组件传过来的值,需要注意defineProps只能在setup语法糖里面使用，不需要import引入
// 父组件不传值的时候可设置默认值
const props = withDefaults(defineProps<Props>(), { 
  user: () => ({ avatar: "" , msg: "", username: "" }),
  userList: () => [],
  message: () => ({ avatar: "" , msg: "", username: "" }),
});
const { user, userList, message } = toRefs(props);
const emits = defineEmits(["sendServer", "handleFile"]);


const room = ref();
const joinUs = ref();

const userListLength = computed(() => {
  return userList.value.length;
});

const iconList = ["icon-liaotianqingqiu", "icon-yonghu"];
const iconCurrentIndex = ref(0);
const joinRoom: any = ref([]);
const messageContent: any = reactive([]); // 0不渲染，1表示自己发出的信息，2表示别人发出的信息


// ------------------------------------------------------------
// 处理输入框的输入，并将输入信息发送给服务器
const content = ref<string>("");
const textarea = ref("");
const handlePress = () => {
  sendContentToServe();
};
const handleEmoji = (emoji: any) => {
  content.value = textarea.value;
  textarea.value += emoji.char;
};
const sendContentToServe = () => {
  // 获取到聊天的内容
  content.value = textarea.value;
  textarea.value = "";
  if (!content.value) {
    return alert("请输入内容");
  }
  //发送给服务器
  emits("sendServer", content.value);
};

const handleCanvas = () => {
  const el = room.value;
  const options = {
    useCORS: true, //支持图片跨域
    // width: el.clientWidth,
    // height: el.clientHeight,
  }
  html2canvas(el, options).then((canvas) => {
    const imgUrl = canvas.toDataURL();
    emits("handleFile", imgUrl); // 交由父对象的handleFile来处理
  });
};

const emojiList: any = ref([]);
const emojiShow = ref<boolean>(false);
const handleEmojiBlur = () => {
  emojiShow.value = false;
};

const getImageUrl = (name: string) => {
  return new URL(`../assets/avatar/${name}`, import.meta.url).href
}
const loadOverImg = () => {
  handleScrollBottom();
};
const handleImage = (file: Message) => {
  handleMessageBox(file);
};
const handleMessageBox = (newValue: Message) => {
  if (newValue.username === user.value.username) {
    // 是自己发的信息
    messageContent.push({ ...newValue, type: 1 });
  } else {
    // 是别人发的信息
    messageContent.push({ ...newValue, type: 2 });
  }
};
const handleFile = (e: any) => {
  const file = e.target.files[0];
  const reader = new FileReader(); // 创建读取文件对象
  reader.readAsDataURL(file); // 发起异步请求，读取文件
  reader.onload = (e) => { // 文件读取完成后，将结果赋值给img的src     
    emits("handleFile", e.target!.result);
  };
};
const haveOneleaveRoom = () => {
  const leaveRoom = interactState.leaveRoom;
  messageContent.push({ ...leaveRoom, type: 3 });
};

const handleScrollBottom = () => {
  const ul = joinUs.value;
  ul.scrollTop = ul.scrollHeight;
};

onMounted(() => {
  joinRoom.value = interactState.joinRoom;
  emojiList.value = emoji;
});

onUpdated(() => {
  handleScrollBottom(); // 聊天定位到底部
})

watch(
  () => message.value,
  (newValue) => {
    handleMessageBox(newValue);
  },
  {
    deep: true,
  }
);

defineExpose({
  handleImage,
  haveOneleaveRoom
})
</script>

<style lang="less" scoped>

.room {
  width: 900px;
  height: 500px;
  border-radius: 8px;
  box-shadow: 0 0 5px rgba(255, 255, 255, 0.9);
  overflow: hidden;
  display: flex;
  color: #333;
  .room-left {
    background-color: rgba(64, 158, 255, 0.8);
    width: 60px;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: 10px;
    .icon-liaotianqingqiu,
    .icon-yonghu {
      font-size: 24px;
      padding-top: 10px;
      cursor: pointer;
    }
    .active {
      color: #ecf0f1;
    }
    img {
      width: 40px;
    }
  }
  .room-center {
    width: 175px;
    background-color: #e6e5e5;
    color: #000;
    display: flex;
    flex-direction: column;
    .center-h {
      padding: 9.6px 10px;
      height: 40px;
      line-height: 40px;
      border-bottom: 1px solid #e5e5e58c;
      box-shadow: 1px 1px 1px #b2c0c9;
      display: flex;
      align-items: center;
      justify-content: center;
      img {
        width: 50px;
        height: 50px;
      }
    }
    .center-b {
      flex: 1;
      .user-item-name {
        padding: 5px 10px;
        height: 40px;
        display: flex;
        align-items: center;
        border-bottom: 1px solid #e5e5e58c;
        box-shadow: 1px 1px 1px #2980b9;
        font-size: 17px;
      }
      .user-item {
        padding: 0 10px;
        margin-top: 5px;
        height: 40px;
        display: flex;
        align-items: center;
        img {
          width: 40px;
          height: 40px;
        }
        span {
          margin-left: 5px;
        }
      }
    }
  }
  .room-right {
    flex: 1;
    background-color: #f6f6f6;
    display: flex;
    flex-direction: column;
    .name {
      display: flex;
      justify-content: center;
      line-height: 40px;
      font-size: 16px;
      border-bottom: 1px solid rgba(100, 100, 100, 0.3);
    }
    .chatcontent {
      height: 300px;
      .join {
        text-align: center;
        color: #ccc;
        overflow: auto;
        height: 300px;
        li {
          padding: 10px;
        }
      }
      .my-message {
        display: flex;
        justify-content: flex-end;
        div {
          display: flex;
          position: relative;
          &::after {
            content: "";
            right: 38px;
            top: 50%;
            transform: translateY(-50%);
            position: absolute;
            border-left: 6px solid #9eea6a;
            border-top: 6px solid transparent;
            border-bottom: 6px solid transparent;
            border-right: 6px solid transparent;
          }
          .file {
            width: 306px;
            height: 170px;
            margin-right: 10px;
            cursor: pointer;
          }
          .avatar {
            width: 40px;
            height: 40px;
          }
          span {
            box-sizing: border-box;
            display: inline-block;
            border-radius: 5px;
            line-height: 32px;
            background-color: #9eea6a;
            color: #000;
            padding: 5px;
            margin-right: 10px;
            min-width: 40px;
          }
        }
      }
      .other-message {
        position: relative;
        display: flex;
        justify-content: flex-start;
        div {
          display: flex;
          position: relative;
          &::before {
            content: "";
            left: 40px;
            top: 55%;
            transform: translateY(-50%);
            position: absolute;
            border-left: 5px solid transparent;
            border-top: 5px solid transparent;
            border-bottom: 5px solid transparent;
            border-right: 5px solid #ccc;
          }
          .file {
            max-width: 306px;
            max-height: 170px;
            margin-top: 14px;
            margin-left: 10px;
            cursor: pointer;
          }
          .avatar {
            width: 40px;
            height: 40px;
          }
          .username {
            position: absolute;
            left: 45px;
            top: -5px;
            font-size: 13px;
            color: #b2b2b2;
          }
          .content {
            margin-top: 12px;
            box-sizing: border-box;
            display: inline-block;
            border-radius: 5px;
            line-height: 32px;
            background-color: #fff;
            color: #000;
            padding: 5px;
            margin-left: 10px;
            border: 1px solid #ccc;
            min-width: 40px;
          }
        }
      }
    }
    .sendMessage {
      position: relative;
      flex: 1;
      background-color: #fff;
      .icon {
        height: 25px;
        padding-top: 6px;
        display: flex;
        align-items: center;
        .icon-smile,
        .icon-wenjianjia,
        .icon-jietu {
          font-size: 20px;
          padding: 0 6px;
          cursor: pointer;
        }
        .icon-jietu {
          font-size: 23px !important;
        }
        .emoji {
          position: absolute;
          display: flex;
          flex-wrap: wrap;
          width: 276px;
          height: 218px;
          overflow: auto;
          bottom: 159px;
          background-color: #fff;
          border: 1px solid #cccccc;
          outline: none;
          span {
            padding: 7px;
            cursor: pointer;
          }
        }
      }
      textarea {
        border: none;
        resize: none;
        outline: none;
        font-size: 15px;
        padding: 9px;
        padding-bottom: 0;
      }
      .btn-sendMessage {
        position: absolute;
        bottom: 10px;
        right: 10px;
        padding: 4px 10px;
      }
    }
  }
  .join {
    color: #333;
    font-size: 13px;
  }
}
</style>
